package sistema;

import controloBD.AcessoBD;
import controloBD.QueryResult;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

public class Aposta {

    private Long id_aposta;
    private String escolha;
    private Double odd;
    private Double stake;
    private String estado;
    private Long id_evento;
    private Long id_utilizador;

    public Aposta(Long id, String escolha, Double odd, Double stake, String estado, Long id_evento, Long id_utilizador) {
        this.id_aposta = id;
        this.escolha = escolha;
        this.odd = odd;
        this.stake = stake;
        this.estado = estado;
        this.id_evento = id_evento;
        this.id_utilizador = id_utilizador;
    }

    public Aposta(String escolha, Double odd, Double stake, String estado, Long id_evento, Long id_utilizador) {
        this.escolha = escolha;
        this.odd = odd;
        this.stake = stake;
        this.estado = estado;
        this.id_evento = id_evento;
        this.id_utilizador = id_utilizador;
    }

    private Aposta(Vector tabela) {
        this.id_aposta = (Long) tabela.get(0);
        this.escolha = (String) tabela.get(1);
        this.odd = (Double) tabela.get(2);
        this.stake = (Double) tabela.get(3);
        this.estado = (String) tabela.get(4);
        this.id_evento = (Long) tabela.get(5);
        this.id_utilizador = (Long) tabela.get(6);
    }

    /**
     * @return the id_aposta
     */
    public Long getId_aposta() {
        return id_aposta;
    }

    /**
     * @return the escolha
     */
    public String getEscolha() {
        return escolha;
    }

    /**
     * @param escolha the escolha to set
     */
    public void setEscolha(String escolha) {
        this.escolha = escolha;
    }

    /**
     * @return the odd
     */
    public double getOdd() {
        return odd;
    }

    /**
     * @param odd the odd to set
     */
    public void setOdd(double odd) {
        this.odd = odd;
    }

    /**
     * @return the stake
     */
    public double getStake() {
        return stake;
    }

    /**
     * @param stake the stake to set
     */
    public void setStake(double stake) {
        this.stake = stake;
    }

    /**
     * @return the estado
     */
    public String getEstado() {
        return estado;
    }

    /**
     * @param estado the estado to set
     */
    public void setEstado(String estado) {
        this.estado = estado;
    }

    /**
     * @return the id_evento
     */
    public Long getId_evento() {
        return id_evento;
    }

    /**
     * @param id_evento the id_evento to set
     */
    public void setId_evento(Long id_evento) {
        this.id_evento = id_evento;
    }

    /**
     * @return the id_utilizador
     */
    public Long getId_utilizador() {
        return id_utilizador;
    }

    /**
     * @param id_utilizador the id_utilizador to set
     */
    public void setId_utilizador(Long id_utilizador) {
        this.id_utilizador = id_utilizador;
    }

    public static void insereAposta(Hashtable params) throws Exception {

        AcessoBD conexao = new AcessoBD();

        String qryName = new String("inserir_nova_aposta");
        conexao.executeUpdate(qryName, params);
        conexao.closeBD();
    }

    public static Aposta devolveAposta(Long id_aposta) throws Exception {

        AcessoBD conexao = new AcessoBD();
        Hashtable<String, String> dadosAposta = new Hashtable<String, String>();
        dadosAposta.put("var_idaposta", id_aposta.toString());
        String qryName = new String("visualizar_por_id_aposta");
        QueryResult qr = conexao.executeSelect(qryName, dadosAposta);
        conexao.closeBD();

        return new Aposta(qr.tabela());
    }

    public static List<Aposta> devolveAposta(Long id_utilizador, String estado) throws Exception {

        AcessoBD conexao = new AcessoBD();
        Hashtable<String, String> dadosAposta = new Hashtable<String, String>();
        dadosAposta.put("var_estado", estado);
        dadosAposta.put("var_idutilizador", id_utilizador.toString());
        String qryName = new String("visualizar_por_estado");
        QueryResult qr = conexao.executeSelect(qryName, dadosAposta);
        conexao.closeBD();

        return converteTabela(qr);
    }

    public static List<Aposta> devolveTodasApostas(Long id_utilizador) throws Exception {

        AcessoBD acesso_bd = new AcessoBD();
        Hashtable<String, String> dadosAposta = new Hashtable<String, String>();
        dadosAposta.put("var_idutilizador", id_utilizador.toString());
        String qryName = new String("visualizar_todas");
        QueryResult qr = acesso_bd.executeSelect(qryName, dadosAposta);

        acesso_bd.closeBD();
        return converteTabela(qr);

    }

    public static List<Aposta> converteTabela(QueryResult qr) {

        List<Aposta> aposta_ut = new LinkedList<Aposta>();
        if (!qr.tabela().isEmpty()) {
            int i = 0;
            while (i != qr.tabela().size()) {
                Long id2 = (Long) qr.tabela().get(i);
                String esc2 = (String) qr.tabela().get(i + 1);
                Double odd2 = (Double) qr.tabela().get(i + 2);
                Double stake2 = (Double) qr.tabela().get(i + 3);
                String estado2 = (String) qr.tabela().get(i + 4);
                Long id_ev2 = (Long) qr.tabela().get(i + 5);
                Long id_ut2 = (Long) qr.tabela().get(i + 6);

                aposta_ut.add((new Aposta(id2, esc2, odd2, stake2, estado2, id_ev2, id_ut2)));
                i = i + 7;
            }
            return aposta_ut;
        }
        return null;
    }

    public static void actualizaResultado(Hashtable<String, String> dados_resultado) throws Exception {

        List<Aposta> lista_apostas = devolvePorIdEvento(dados_resultado.get("var_idevento"));
        List<Aposta> lista_vencedoras = verificaQuemGanha(lista_apostas, dados_resultado);

        for (Aposta a : lista_vencedoras) {
            Double lucro = a.getStake() * a.getOdd();
            Double saldo = Utilizador.devolveSaldo(a.getId_utilizador());

            Double total = saldo + lucro;

            Hashtable<String, String> dados_actualizar = new Hashtable<String, String>();
            dados_actualizar.put("var_saldo", total.toString());
            dados_actualizar.put("var_idutilizador", a.getId_utilizador().toString());
            Utilizador.actualizaSaldo(dados_actualizar);
        }
    }

    private static List<Aposta> devolvePorIdEvento(String id_evento) throws Exception {

        AcessoBD conexao = new AcessoBD();
        Hashtable<String, String> dadosAposta = new Hashtable<String, String>();
        dadosAposta.put("var_idevento", id_evento);
        String qryName = new String("devolvePorIdEvento");
        QueryResult qr = conexao.executeSelect(qryName, dadosAposta);
        conexao.closeBD();

        return converteTabela(qr);
    }

    private static void fecharAposta(Long id_aposta, String resultado) throws Exception {
        AcessoBD conexao = new AcessoBD();
        Hashtable<String, String> dadosAposta = new Hashtable<String, String>();
        dadosAposta.put("var_idaposta", id_aposta.toString());
        dadosAposta.put("var_estado", resultado);
        String qryName = new String("fechaAposta");
        conexao.executeUpdate(qryName, dadosAposta);
        conexao.closeBD();
    }

    private static List<Aposta> verificaQuemGanha(List<Aposta> lista_apostas, Hashtable<String, String> dados_resultado) throws Exception {
        List<Aposta> apostas_vencedoras = new LinkedList<Aposta>();

        for (Aposta a : lista_apostas) {
            if (a.getEscolha().equals(dados_resultado.get("var_resultado"))) {
                fecharAposta(a.getId_aposta(), "ganha");
                apostas_vencedoras.add(a);
            } else if (a.escolha.equals("over")) {
                Integer golos1 = Integer.parseInt(dados_resultado.get("var_golos1"));
                Integer golos2 = Integer.parseInt(dados_resultado.get("var_golos2"));
                if (golos1 > golos2) {
                    fecharAposta(a.getId_aposta(), "ganha");
                    apostas_vencedoras.add(a);
                } else {
                    fecharAposta(a.getId_aposta(), "perdida");
                }
            } else if (a.escolha.equals("under")) {
                Integer golos1 = Integer.parseInt(dados_resultado.get("var_golos1"));
                Integer golos2 = Integer.parseInt(dados_resultado.get("var_golos2"));
                if (golos1 < golos2) {
                    fecharAposta(a.getId_aposta(), "ganha");
                    apostas_vencedoras.add(a);
                } else {
                    fecharAposta(a.getId_aposta(), "perdida");
                }
            } else {
                fecharAposta(a.getId_aposta(), "perdida");
            }
        }
        return apostas_vencedoras;
    }
}
